/*================================================================
*   Copyright (C) 2024 baichao All rights reserved.
*
*   文件名称：false_sharing.c
*   创 建 者：baichao
*   创建日期：2024年03月21日
*   描    述：
*
================================================================*/

/*
 * 填充行之前：Elapsed time: 153796 ms
 * 填充行之后：Elapsed time: 60619 ms
 * 填充行通过填充字节，使得它们的地址之间的距离达到缓存行大小（通常为64字节），这样就能够确保不同变量被分配到不同的缓存行中，避免了伪共享问题。
 */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#define ITERATIONS 1000000000
#define ARRAY_SIZE 16

struct data {
  int value;
  char padding[60];
};

struct data array[ARRAY_SIZE];

void *add(void *arg) {
  int id = *(int *)arg;

  for (int i = id; i < ARRAY_SIZE; i += 2) {
    for (int j = 0; j < ITERATIONS; j++) {
      array[i].value++;
    }
  }

  return NULL;
}

int main(int argc, char *argv[]) {
  struct timeval start, end;
  long long diff;

  gettimeofday(&start, NULL);

  pthread_t t1, t2;
  int id1 = 0, id2 = 1;

  if (pthread_create(&t1, NULL, add, &id1)) {
    perror("pthread_create");
    exit(1);
  }

  if (pthread_create(&t2, NULL, add, &id2)) {
    perror("pthread_create");
    exit(1);
  }

  if (pthread_join(t1, NULL)) {
    perror("pthread_join");
    exit(1);
  }

  if (pthread_join(t2, NULL)) {
    perror("pthread_join");
    exit(1);
  }

  gettimeofday(&end, NULL);

  diff =
      (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000;

  printf("Elapsed time: %lld ms\n", diff);

  printf("\n");

  return 0;
}
